using System;
using System.Management;
using System.Reflection;
using System.Net;

namespace Zivsoft.Log
{
    /// <summary>
    /// Provides access to machine-specific data.
    /// </summary>
    /// <remarks>
    /// This class cannot be inherited nor instantiated.
    /// </remarks>
    sealed class MachineInfo : MarshalByRefObject
    {

        /// <summary>
        /// This function returns the Machine Name, or an empty string on failure.
        /// </summary>
        public static string MachineName
        {
            get
            {
                return Environment.MachineName;
            }
        }


        /// <summary>
        /// This function returns the Hard Drive Size, or an empty string on failure.
        /// </summary>
        public static string HardDriveSize
        {
            get
            {
                try
                {
                    ManagementObject diskinfo = new ManagementObject("win32_logicaldisk.deviceid=\"C:\"");
                    diskinfo.Get();
                    return diskinfo["Size"].ToString();
                }
                catch
                {
                    return string.Empty;
                }
            }
        }


        /// <summary>
        /// This function returns the Hard Disk Free Space, or 0 on failure.
        /// </summary>
        public static long HardDriveFreeSpace
        {
            get
            {
                try
                {
                    ManagementObject diskinfo = new ManagementObject("win32_logicaldisk.deviceid=\"C:\"");
                    diskinfo.Get();
                    return Convert.ToInt64(diskinfo["FreeSpace"]);
                }
                catch (Exception e)
                {
                    Factory.FileLog.LogError("{0}",e);
                    return 0;
                }
            }
        }


        /// <summary>
        /// This function returns the total Physical Memory, or an empty string on failure.
        /// </summary>
        public static string TotalPhysicalMemory
        {
            get
            {
                try
                {
                    string output = null;
                    ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_ComputerSystem");
                    ManagementObjectCollection queryCollection1 = query1.Get();
                    foreach (ManagementObject mo in queryCollection1)
                    {
                        output = mo["totalphysicalmemory"].ToString();
                        break;
                    }
                    return output;
                }
                catch
                {
                    return string.Empty;
                }
            }
        }


        /// <summary>
        /// This function returns the amount of free memory, or 0 on failure.
        /// </summary>
        public static long FreeMemory
        {
            get
            {
                try
                {
                    long output = 0L;
                    ManagementObjectSearcher query = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");
                    ManagementObjectCollection queryCollection1 = query.Get();
                    foreach (ManagementObject mo in queryCollection1)
                    {
                        output = Convert.ToInt64(mo["FreePhysicalMemory"]);
                        break;
                    }
                    return output;
                }
                catch (Exception e)
                {

                    Factory.FileLog.LogError("{0}",e);
                    return 0;
                }
            }
        }


        /// <summary>
        /// This function returns the OS Version, or an empty string on failure.
        /// </summary>
        public static string OSVersion
        {
            get
            {
                return Environment.OSVersion.ToString();
            }
        }


        /// <summary>
        /// This function returns the Language of OS, or an empty string on failure.
        /// </summary>
        public static string OSLanguage
        {
            get
            {
                try
                {
                    string output = null;
                    ManagementObjectSearcher query1 = new ManagementObjectSearcher("SELECT * FROM Win32_OperatingSystem");
                    ManagementObjectCollection queryCollection1 = query1.Get();
                    foreach (ManagementObject mo in queryCollection1)
                    {
                        output = mo["OSLanguage"].ToString();
                        break;
                    }
                    return output;
                }
                catch
                {
                    return string.Empty;
                }
            }
        }


        /// <summary>
        /// This function returns the IP address, or an empty string on failure.
        /// </summary>
        public static string IP
        {
            get
            {
                var ips= Dns.GetHostAddresses(Environment.MachineName);
                if (ips == null)
                {
                    return IPAddress.Loopback.ToString();
                }
                string output = string.Empty;
                for (int i = 0; i < ips.Length; i++)
                {
                    if (!ips[i].IsIPv6LinkLocal)
                    {

                        output = ips[i].ToString();
                        break;
                    }
                }
                return output;
            }
        }

        /// <summary>
        /// This function returns the Installed/ Current version of  Messenger Client 
        /// </summary>
        /// <returns>The version of the application, or an empty string on failure.</returns>
        public static string LoggerVersion
        {
            get
            {
                try
                {
                    return Assembly.GetExecutingAssembly().GetName().Version.ToString();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e);
                    return string.Empty;
                }
            }
        }
    }
}